# _*_ coding:utf-8 _*_
# @Time  : 2023.08.23
# @Author: zizlee
from fastapi import APIRouter, Body, Depends, Query
from pydantic import BaseModel, validator
from db_utils import BaseDatabaseConnection
from utils.jwt_token import TokenPayload
from utils.hutool_utils import DatlibUtils
from response import APIResponse


class CreateFormulaItem(BaseModel):
    group_id: int
    name: str
    formula: str
    unit: str
    vcode: str
    apply: bool

    @validator('formula')
    def validate_formula(cls, value):
        if not value:
            raise ValueError('公式配置不能为空!')
        try:
            r = eval(value.replace('i', ''))
            print(r)
        except Exception as e:
            raise ValueError('公式表达式不合法: {}'.format(e))
        return str((value, "line")).replace("'", '"')


class DataIndex:
    def __init__(self, index_id: int = None):
        self.index_id = index_id

    def add_reading_count(self):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("UPDATE datlib_index SET hot=hot+1 WHERE id=%s;", (self.index_id,))
        return APIResponse.success()

    def get_reading_rank(self, rank: int):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("SELECT id,name,unit,hot,end_value FROM datlib_index WHERE is_active=1 ORDER BY hot DESC LIMIT %s;", [rank])
            index_list = list(conn.cursor.fetchall())
        for i in index_list:
            i['show_name'] = i['name']
            i['tooltip'] = False
            if i['unit']:
                i['show_name'] += f'({i["unit"]})'
            if len(i['show_name']) > 20:
                if i['unit']:
                    i['show_name'] = i['name'][:15] + f'...({i["unit"]})'
                else:
                    i['show_name'] = i['name'][:18] + f'...'
                i['tooltip'] = True
            if i['end_value'] and len(str(i['end_value'])) > 10:
                i['show_value'] = f'{round(i["end_value"] / 10000, 1)}万'
            else:
                i['show_value'] = i['end_value']
        return APIResponse.success(data=index_list)

    def create_calculate_formula(self, payload, fitem: CreateFormulaItem):
        sql = """
            INSERT INTO datlib_group_index (group_id,name,is_formula,formula,unit,vcode,is_apply,user_id) 
            VALUES (%s,%s,%s,%s,%s,%s,%s,%s);
        """
        prm = [fitem.group_id, fitem.name, 1, fitem.formula, fitem.unit, fitem.vcode, fitem.apply, payload.user_id()]
        # print(prm)
        formula = eval(fitem.formula)[0]
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute(sql, prm)
            conn.cursor.execute("SELECT LAST_INSERT_ID() As lid;")
            last_id = conn.cursor.fetchone()['lid']

            index_ids = DatlibUtils.formula2ids(formula=formula)
            conn.cursor.execute("""
                SELECT id,name,plat,plat_id,db_name,tb_name,frequency,unit,start_date,end_date FROM datlib_index WHERE id IN %s;
            """, [index_ids])
            index_list = list(conn.cursor.fetchall())
        start_date, end_date, frequency = DatlibUtils.public_date_range_frequency(index_list)
        resp = {
            'id': last_id,
            'iid': None,  # 与查询组下指标接口返回一致
            'name': fitem.name,
            'frequency': frequency,
            'unit': fitem.unit,
            'source': '',
            'formula': formula,
            'start_date': start_date,
            'end_date': end_date
        }
        return APIResponse.success(data=resp)


dat_index_api = APIRouter()


@dat_index_api.post('/reading/')  # 指标的点击量
def data_index_reading(iid: int = Body(embed=True)):
    return DataIndex(index_id=iid).add_reading_count()


@dat_index_api.get('/reading/')  # 点击量排名
def reading_rank(rank: int = Query(8)):
    return DataIndex().get_reading_rank(rank=rank)

@dat_index_api.post('/formula/')  # 用户添加一个计算公式
def create_calculate_formula(payload: TokenPayload = Depends(TokenPayload), formula_item: CreateFormulaItem = Body(...)):
    return DataIndex().create_calculate_formula(payload=payload, fitem=formula_item)



